package com.zmj.sy.mom.srv.aps.controller;

import com.zmj.sy.mom.srv.aps.bean.entity.resource.LogApi;
import com.zmj.sy.mom.srv.aps.bean.vo.base.*;
import com.zmj.sy.mom.srv.aps.bean.vo.lantek.LantekPushSelectListVo;
import com.zmj.sy.mom.srv.aps.bean.vo.nest.*;
import com.zmj.sy.mom.srv.aps.bean.vo.nest.release.NestReleasePartVo;
import com.zmj.sy.mom.srv.aps.bean.vo.nest.release.NestReleasePlateVo;
import com.zmj.sy.mom.srv.aps.bean.vo.nest.workspace.*;
import com.zmj.sy.mom.srv.aps.bean.vo.nestpre.LantekNewPrePlanVo;
import com.zmj.sy.mom.srv.aps.bean.vo.nestpre.LantekPrePushPlan;
import com.zmj.sy.mom.srv.aps.bean.vo.nestpre.LantekPrePushReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.plate.PlateListReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.plate.PlateListResVo;
import com.zmj.sy.mom.srv.aps.service.NestService;
import com.zmj.sy.mom.srv.aps.utils.LogApiUtils;
import com.zmj.sy.mom.srv.aps.utils.SySecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RequiredArgsConstructor
@Api(tags = "套料")
@RestController
@RequestMapping("/nest")
public class NestController {

    private final LogApiUtils logApiUtils;

    private final NestService nestService;

    @ApiOperation("正式套料 - 推送计划 - 列表")
    @GetMapping("/proPushPlanList")
    public BasePageResVo<NestProPushListPlanResVo> proPushPlanList(NestProPushListPlanReqVo reqVo) {
        return nestService.proPushPlanList(reqVo);
    }

    @ApiOperation("工作区-新增：默认为当前人")
    @PostMapping("/workspaceAdd")
    public BaseResVo workspaceAdd(@RequestBody NestWorkspaceAddReqVo reqVo) {
        nestService.workspaceAdd(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("工作区-列表：只列当前套料人")
    @GetMapping("/workspaceList")
    public BaseListResVo<NestWorkspaceListResVo> workspaceList(NestWorkspaceListReqVo reqVo) {
        String userCode = SySecurityUtils.getUserCode();
        if(userCode.equals("000000")){
            return BaseListResVo.empty();
        }
        reqVo.setUserCode(userCode);
        return new BaseListResVo<>(nestService.workspaceList(reqVo));
    }

    @ApiOperation("工作区-列表：所有人的套料列表")
    @GetMapping("/workspaceAll")
    public BaseListResVo<NestWorkspaceAllResVo> workspaceAll() {
        return new BaseListResVo<>(nestService.workspaceAll());
    }

    @ApiOperation("工作区-关闭")
    @PostMapping("/workspaceClose")
    public BaseResVo workspaceClose(@RequestBody BaseIdReqVo reqVo) {
        // 释放所有计划，释放所有钢板，状态改为关闭，在工作区不可见
        nestService.workspaceClose(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("工作区-完成")
    @PostMapping("/workspaceFinish")
    public BaseResVo workspaceFinish(@RequestBody BaseIdReqVo reqVo) {
        // 释放工作区所有未套完的钢板和零件，状态改为完成，工作区不可见（或者当天可见)
        nestService.workspaceFinish(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("工作区-撤销套料")
    @PostMapping("/workspaceCancel")
    public BaseResVo workspaceCancel(@RequestBody BaseIdReqVo reqVo) {
        // 找到当前工作区，撤销该工作区的计划，撤销该工作区的钢板，状态改为撤销，撤销数量，完成时间改为null
        nestService.workspaceCancel(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("工作区-推送套料计划")
    @PostMapping("/workspacePush")
    public BaseResVo workspacePush(@RequestBody BaseIdReqVo reqVo) {
        // 谁触发谁就是套料人，推送时字段取创建人字段
        // 找到当前工作区，推送工作区中未推送的计划，推送工作区中未推送的钢板，首次回填工作区编号，其余的时候推送该编号
        nestService.workspacePush(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("工作区-推送套料计划-推送计划")
    @PostMapping("/workspacePushPlan")
    public BaseResVo workspacePushPlan(@RequestBody BaseIdReqVo reqVo) {
        nestService.workspacePushPlan(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("工作区-推送套料计划-推送钢板")
    @PostMapping("/workspacePushPlate")
    public BaseResVo workspacePushPlate(@RequestBody BaseIdReqVo reqVo) {
        nestService.workspacePushPlate(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("工作区-接收套料结果")
    @PostMapping("/workspaceReceive")
    public BaseResVo workspaceReceive() {
        // 接收套料结果，更新计划，更新钢板，更新状态，更新完成时间
        // 判断状态是否为套料完成，如果是完成走更新流程，如果是新增走新增流程。
        return BaseResVo.ok();
    }

    @ApiOperation("零件-绑定工作区下的零件列表")
    @GetMapping("/partBindList")
    public BaseListResVo<NestPartBindListResVo> partBindList(NestPartBindReqVo reqVo) {
        return new BaseListResVo<>(nestService.partBindList(reqVo));
    }

    @ApiOperation("零件-零件选择器")
    @GetMapping("/partUnbindList")
    public BasePageResVo<NestPartUnbindListResVo> partUnbindList(NestPartUnbindListReqVo reqVo) {
        return nestService.partUnbindList(reqVo);
    }

    @ApiOperation("零件-移入到工作区")
    @PostMapping("/partIn")
    public BaseResVo partIn(@RequestBody NestPartInReqVo reqVo) {
        nestService.partIn(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("零件-移出工作区")
    @PostMapping("/partOut")
    public BaseResVo partOut(@RequestBody BaseIdReqVo reqVo) {
        nestService.partOut(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("钢板-绑定工作区下的钢板列表")
    @GetMapping("/plateBindList")
    public BaseListResVo<PlateListResVo> plateBindList(BaseIdReqVo reqVo) {
        return nestService.plateBindList(reqVo);
    }

    @ApiOperation("钢板-钢板选择器")
    @GetMapping("/plateUnbindList")
    public BasePageResVo<PlateListResVo> plateUnbindList(PlateListReqVo reqVo) {
        return nestService.plateUnbindList(reqVo);
    }

    @ApiOperation("钢板-移入到工作区")
    @PostMapping("/plateIn")
    public BaseResVo plateIn(@RequestBody NestPlateInReqVo reqVo) {
        // 查是否为进行中的钢板，如果不是的
        nestService.plateIn(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("钢板-移出工作区")
    @PostMapping("/plateOut")
    public BaseResVo plateOut(@RequestBody BaseIdReqVo reqVo) {
        // 物理删
        nestService.plateOut(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("推送-零件-列表")
    @GetMapping("/pushPartList")
    public BaseResVo pushPartList() {
        return BaseResVo.ok();
    }

    @ApiOperation("推送-零件-新增")
    @PostMapping("/pushPartAdd")
    public BaseResVo pushPartAdd(@RequestBody BaseIdsReqVo reqVo) {
        // 此处选择是推送到海克思康还是兰特克。
        // 如何唯一定位一个零件？ orderId + partId
         nestService.pushPartAdd(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("推送-零件-推送")
    @PostMapping("/pushPartPush")
    public BaseResVo pushPartPush() {
        nestService.pushPartPush();
        return BaseResVo.ok();
    }

    @ApiOperation("推送-计划-列表")
    @GetMapping("/pushPlanList")
    public BaseResVo pushPlanList() {
        return BaseResVo.ok();
    }

    @ApiOperation("推送-计划-新增")
    @PostMapping("/pushPlanAdd")
    public BaseResVo pushPlanAdd(@RequestBody BaseIdsReqVo reqVo) {
        // 此次有一个策略方法，是推送海克思康还是兰特克。
        // 如何唯一定位一次套料计划： orderId + planId
         nestService.pushPlanAdd(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("预套料推送-零件-新增")
    @PostMapping("/pushPrePartAdd")
    public BaseResVo pushPrePartAdd(@RequestBody LantekPrePushReqVo reqVo) {
        nestService.pushPrePartAdd(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("预套料推送-零件-推送")
    @PostMapping("/pushPrePartPush")
    public BaseResVo pushPrePartPush() {
        nestService.pushPrePartPush();
        return BaseResVo.ok();
    }

    @ApiOperation("预套料推送-计划-新增")
    @PostMapping("/pushPrePlanAdd")
    public BaseResVo pushPrePlanAdd(@RequestBody LantekPrePushReqVo reqVo) {
        nestService.pushPrePlanAdd(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("预套料推送-计划-推送选择界面")
    @GetMapping("/pushSelect")
    public BaseListResVo<LantekPushSelectListVo> pushSelect(BaseIdReqVo reqVo) {
        return nestService.pushSelect(reqVo);
    }

    @ApiOperation("预套料推送-计划-推送")
    @PostMapping("/pushPrePlanPush")
    public BaseResVo pushPrePlanPush(@RequestBody LantekPrePushPlan reqVo) {
        nestService.pushPrePlanPush(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("预套料-计划-新")
    @PostMapping("/pushPrePlanNew")
    public BaseResVo pushPrePlanNew(@RequestBody LantekNewPrePlanVo reqVo) {
        nestService.pushPrePlanNew(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("接收套料结果——兰特克预套料")
    @PostMapping("/receiveNestPre")
    public BaseResVo receiveNestPre(@RequestBody String body) {
        log.info("接收套料结果:{}", body);
        LogApi logApi = logApiUtils.getReceiveLog("兰特克预套料", "接收预套料结果", "/nest/receiveNestPre");
        Map<String, String> resVo = new HashMap<>();
        try {
            logApiUtils.setReqStr(logApi, body);
            nestService.receiveNestPre(body);
            logApiUtils.successAndSave(logApi, resVo);
        } catch (Exception e) {
            e.printStackTrace();
            logApiUtils.errorAndSave(logApi, resVo, e.getMessage());
            return BaseResVo.fail(e.getMessage());
        }
        return BaseResVo.ok();
    }

    @ApiOperation("接收套料结果——兰特克正式套料")
    @PostMapping("/receiveNest")
    public BaseResVo receiveNest(@RequestBody String body) {
        log.info("接收套料结果:{}", body);
        LogApi logApi = logApiUtils.getReceiveLog("兰特克正式套料", "接收套料结果", "/nest/receiveNest");
        Map<String, String> resVo = new HashMap<>();
        try {
            logApiUtils.setReqStr(logApi, body);
            nestService.receiveNest(body);
            logApiUtils.successAndSave(logApi, resVo);
        } catch (Exception e) {
            e.printStackTrace();
            logApiUtils.errorAndSave(logApi, resVo, e.getMessage());
            return BaseResVo.fail(e.getMessage());
        }
        return BaseResVo.ok();
    }

    @ApiOperation("接收套料结果——海克思康")
    @PostMapping("/receiveNestHexagon")
    public BaseResVo receiveNestHexagon(@RequestBody String body) {
        log.info("接收套料结果:{}", body);
        LogApi logApi = logApiUtils.getReceiveLog("海克斯康套料", "接收海克斯康套料", "/nest/receiveNestHexagon");
        Map<String, String> resVo = new HashMap<>();
        try {
            logApiUtils.setReqStr(logApi, body);
            nestService.receiveNestHexagon(body);
            logApiUtils.successAndSave(logApi, resVo);
        } catch (Exception e) {
            e.printStackTrace();
            logApiUtils.errorAndSave(logApi, resVo, e.getMessage());
            return BaseResVo.fail(e.getMessage());
        }
        return BaseResVo.ok();
    }

    @ApiOperation("推送管理界面——部分选择——海克斯康")
    @PostMapping("pushManHex")
    public BaseResVo pushManHex(@RequestBody NestProPushHexReqVo reqVo) {
        nestService.pushManHex(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("推送管理界面——部分选择——兰特克")
    @PostMapping("pushManLan")
    public BaseResVo pushManLan(@RequestBody NestProPushLanReqVo reqVo) {
        nestService.pushManLan(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("推送管理界面——全部——海克斯康")
    @PostMapping("pushManAllHex")
    public BaseResVo pushManAllHex(@RequestBody NestProPushHexAllReqVo reqVo) {
        nestService.pushManAllHex(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("推送管理界面——全部——兰特克")
    @PostMapping("pushManAllLan")
    public BaseResVo pushManAllLan(@RequestBody NestProPushLanAllReqVo reqVo) {
        nestService.pushManAllLan(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("推送管理界面——重新推送")
    @PostMapping("pushManRePush")
    public BaseResVo pushManRePush(@RequestBody NestProPushLanReqVo reqVo) {
        nestService.pushManRePush(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("作业区-一键释放零件")
    @PostMapping("releasePart")
    public BaseResVo releasePart(@RequestBody BaseIdReqVo reqVo) {
//        nestService.releasePart(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("作业区-一键释放钢板")
    @PostMapping("releasePlate")
    public BaseResVo releasePlate(@RequestBody BaseIdReqVo reqVo) {
//        nestService.releasePlate(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("作业区-释放零件-单条")
    @PostMapping("releasePartOne")
    public BaseResVo releasePartOne(@RequestBody BaseIdReqVo reqVo) {
        nestService.releasePartOne(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("作业区-释放钢板-单条")
    @PostMapping("releasePlateOne")
    public BaseResVo releasePlateOne(@RequestBody BaseIdReqVo reqVo) {
        nestService.releasePlateOne(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("兰特克释放钢板——APS")
    @PostMapping("/releasePlateLan")
    public BaseResVo releasePlateLan(@RequestBody List<NestReleasePlateVo> list) {
        nestService.releasePlateLan(list);
        return BaseResVo.ok();
    }

    @ApiOperation("兰特克释放计划——APS")
    @PostMapping("/releasePlanLan")
    public BaseResVo releasePlanLan(@RequestBody NestReleasePartVo reqVo) {
        nestService.releasePlanLan(reqVo);
        return BaseResVo.ok();
    }

    // TODO 8月14日打开指定套料图和双击打开作业区
    @ApiOperation("打开兰特克指定套料图")
    @PostMapping("/openNestDraw")
    public BaseResVo openNestDraw(@RequestBody LantekProOpenReqVo reqVo) {
        nestService.openNestDraw(reqVo);
        return BaseResVo.ok();
    }

    // TODO 抽出套料写入部分，各自对应策略处理为标准数据，再进行存储
    @ApiOperation("APS抽出套料写入功能")
    @PostMapping("/nestInfoWrite")
    public BaseResVo nestInfoWrite(@RequestBody NestReceiveReqVo reqVo) {
        nestService.nestInfoWrite(reqVo);
        return BaseResVo.ok();
    }

    // TODO 8月13日制定套料推送流程
    /**
     * 订单拆包时将图纸信息同步到图纸推送表
     * 排产发布时将切割计划信息同步到计划推送表
     * 选择推送海克斯康，直接进行推送，按照原逻辑，写入package_push表
     * 选择推送兰特克，打上标签，进到套料数据库，勾选计划进行推送，取消作业区字段，获取返回结果的作业区信息在本地创建作业区，记录作业区及钢板、零件信息（重写）
     * 选择推送兰特克，打上标签，进到套料数据库，勾选计划进行推送，先根据工号、切割工作组、规格等信息为作业区编码推送兰特克创建作业区，后根据作业区编码进行推送计划到指定作业区下
     * 单个工号同一时间只能存在一个激活中（套料中）的作业区
     * 选择钢板进行推送，根据工号查询激活中的作业区，推送到指定的作业区下
     * 计划释放和钢板释放功能验证，不妨碍其他账号调用计划和钢板
     * 套料完成后回填数据，不同的接口处理不同方的数据，整理成标准数据后进行回填
     * 推送时厚度校验，钢板推送时增加钢板材质与作业区材质的校验
     */

    @ApiOperation("套料作业区——订单——推送兰特克")
    @PostMapping("pushOrderLan")
    public BaseResVo pushOrderLan(@RequestBody NestProPushLanReqVo reqVo) {
        nestService.pushOrderLan(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("套料作业区——订单——推送作业区下拉框")
    @PostMapping("pushSelectSpace")
    public BaseListResVo<NestWorkspaceListResVo> pushSelectSpace() {
        return nestService.pushSelectSpace();
    }

    @ApiOperation("套料作业区——在库板材-推送兰特克")
    @PostMapping("/pushPlateLan")
    public BaseResVo pushPlateLan(@RequestBody NestPlateInReqVo reqVo) {
        nestService.pushPlateLan(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("套料作业区——创建作业区（兰特克————材质δ厚度δ工作组）")
    @GetMapping("/createWorkPlace")
    public BaseResVo createWorkPlace(String norm) {
        String[] split = norm.split("δ");
        String texture = split[0];
        Integer thickness = Integer.parseInt(split[1]);
        String groupCode = split[2];
        nestService.createWorkPlace(texture, thickness, groupCode);
        return BaseResVo.ok();
    }

    @ApiOperation("手动输入钢板信息进行推送")
    @PostMapping("/handPlatePost")
    public BaseResVo handPlatePost(@RequestBody NestPlatePushReqVo reqVo) {
        nestService.handPlatePost(reqVo);
        return BaseResVo.ok();
    }

    @ApiOperation("手动推送预套料信息")
    @PostMapping("/handPostPre")
    public BaseResVo handPostPre(@RequestBody Integer id) {
        nestService.handPostPre(id);
        return BaseResVo.ok();
    }

    @ApiOperation("接收套料结果——兰特克正式套料——处理标准数据")
    @PostMapping("/receiveNestNewLan")
    public BaseResVo receiveNestNewLan(@RequestBody String body) {
        log.info("接收套料结果:{}", body);
        LogApi logApi = logApiUtils.getReceiveLog("兰特克正式套料", "接收套料结果", "/nest/receiveNestNewLan");
        Map<String, String> resVo = new HashMap<>();
        try {
            logApiUtils.setReqStr(logApi, body);
            nestService.receiveNestNewLan(body, logApi);
            logApiUtils.successAndSave(logApi, resVo);
        } catch (Exception e) {
            e.printStackTrace();
            logApiUtils.errorAndSave(logApi, resVo, e.getMessage());
            return BaseResVo.fail(e.getMessage());
        }
        return BaseResVo.ok();
    }

    @ApiOperation("接收套料结果——海克思康——处理标准数据")
    @PostMapping("/receiveNestNewHex")
    public BaseResVo receiveNestNewHex(@RequestBody String body) {
        log.info("接收套料结果:{}", body);
        LogApi logApi = logApiUtils.getReceiveLog("海克斯康套料", "接收海克斯康套料", "/nest/receiveNestNewHex");
        Map<String, String> resVo = new HashMap<>();
        try {
            logApiUtils.setReqStr(logApi, body);
            nestService.receiveNestNewHex(body, logApi);
            logApiUtils.successAndSave(logApi, resVo);
        } catch (Exception e) {
            e.printStackTrace();
            logApiUtils.errorAndSave(logApi, resVo, e.getMessage());
            return BaseResVo.fail(e.getMessage());
        }
        return BaseResVo.ok();
    }

}
